package ps.client.plugin.eq2.log;

import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class LogParser {
	
	public static final String NO_REGEX = ".*";

	String currentAvatarName = "John";
	String currentAvatarServer = "Do";
	
	Hashtable<String, Vector<ParserListener>> regexToListener = new Hashtable<String, Vector<ParserListener>>();
	Hashtable<String, Pattern> patternTable = new Hashtable<String, Pattern>();
	Vector<Trigger> triggerList = new Vector<Trigger>();
	
	public void parse(String line) {
	    try {
    		LogLine logLine = new LogLine(this, line);
    		Enumeration<String> regex = regexToListener.keys();
    		while (regex.hasMoreElements()) {
    			String elem = regex.nextElement();
    			if (elem == NO_REGEX) {
    				fireParserEvent(NO_REGEX, logLine);
    			} else if (patternTable.get(elem).matcher(logLine.getContent()).matches()) {
    				fireParserEvent(elem, logLine);
    			}
    		}
    		for (int i = 0; i < triggerList.size(); i++) {
    			Trigger trigger = triggerList.get(i);
    			int type = logLine.getType();
    			int flags = trigger.getFlags();
    			boolean dontParse = !trigger.isEnabled()
    				|| ((type == LogLine.TYPE_CHAT) && ((flags & Trigger.IGNORE_CHAT) > 0))
    				|| ((type != LogLine.TYPE_CHAT) && ((flags & (Trigger.CHAT_ONLY + Trigger.CHAT_MSG_ONLY)) > 0))
    				|| (trigger.isHitBefore() && (trigger.getMinSecondsBetweenHits() > 0) && ((System.currentTimeMillis() - trigger.getLastHit()) / 1000) < trigger.getMinSecondsBetweenHits());
    			if (!dontParse) {
    				Matcher matcher = null;
    				if ((flags & Trigger.CHAT_MSG_ONLY) == 0) {
    					matcher = trigger.getPattern().matcher(logLine.getContent());
    				} else {
    					matcher = trigger.getPattern().matcher(logLine.getChatLine().getMessage());
    				}
    				if (matcher.matches()) {
    					TriggerEvent triggerEvent = new TriggerEvent(trigger, logLine, matcher);
    					trigger.fireTriggerEvent(triggerEvent);
    				}
    			}
    		}
	    } catch (Exception ex) {
	        ex.printStackTrace();
//	        ErrorDialog.show(ex, "Es ist ein Fehler beim Parsen aufgetreten.\r\n\r\n"
//	                + "Logzeile: " + line);
        }
	}
	
	public void addParserListener(ParserListener listener) {
		addParserListener(listener, NO_REGEX);
	}
	
	public void addParserListener(ParserListener listener, String regex) {
		if (!patternTable.containsKey(regex)) {
			 patternTable.put(regex, Pattern.compile(regex));
		}
		if (regexToListener.containsKey(regex)) {
			Vector<ParserListener> listenerList = regexToListener.get(regex);
			if (!listenerList.contains(listener)) {
				listenerList.add(listener);
			}
		} else {
			Vector<ParserListener> listenerList = new Vector<ParserListener>();
			listenerList.add(listener);
			regexToListener.put(regex, listenerList);
		}
	}
	
	public void removeParserListener(ParserListener listener) {
		Enumeration<String> regex = regexToListener.keys();
		while (regex.hasMoreElements()) {
			String key = regex.nextElement();
			Vector<ParserListener> listenerList = regexToListener.get(key);
			listenerList.remove(listener);
			if (listenerList.size() == 0) {
				regexToListener.remove(key);
			}
		}
	}
	
	public void parseLogFilePath(String path) {
		File file = new File(path);
		String logName = file.getName();
		currentAvatarServer = file.getParentFile().getName();
		currentAvatarServer = currentAvatarServer.substring(0, 1).toUpperCase() +
				currentAvatarServer.substring(1).toLowerCase();
		
		if (logName.matches("eq2log_.+\\.txt")) {
			currentAvatarName = logName.substring(7, logName.lastIndexOf(".txt"));
			currentAvatarName = currentAvatarName.substring(0, 1).toUpperCase() +
					currentAvatarName.substring(1).toLowerCase();
		}
	}
	
	void fireParserEvent(String regex, LogLine logLine) {
		Vector<ParserListener> listenerList = regexToListener.get(regex);
		ParserEvent parserEvent = new ParserEvent(this, logLine, regex);
		for (int i = 0; i < listenerList.size(); i++) {
			listenerList.get(i).parserEvent(parserEvent);
		}
	}
	
	public String getCurrentAvatarName() {
		return currentAvatarName;
	}
	
	public String getCurrentAvatarServer() {
		return currentAvatarServer;
	}
	
	public void addTrigger(Trigger trigger) {
		if (!triggerList.contains(trigger)) {
			triggerList.add(trigger);
		}
	}

	public void removeTrigger(Trigger trigger) {
		triggerList.remove(trigger);
	}
}
